package game.view;

import game.control.GameController;
import game.model.GameModels;
import game.model.Position;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.List;

/**
 * 游戏界面
 *
 * @see GameController
 * @see GameModels
 */
public class GameWindow extends JFrame {
    public static final String TITLE = "贪吃蛇";

    private static final int UNIT = 50; // 单位长，从模型坐标到屏幕坐标
    private static final Position MODEL_OFFSET = new Position(UNIT, UNIT); // 模型地图在屏幕上的起始偏移
    private static final int TIMER_CYCLE = 500; // 计时器周期，强制移动蛇

//    public final int WINDOWS_WIDTH;
//    public final int WINDOWS_HEIGHT;

    /**
     * 构造函数，窗口的相关参数在此初始化
     *
     * @param calleeWindow 父窗口
     * @param controller   游戏控制器
     * @param models       游戏模型
     */
    public GameWindow(Component calleeWindow, GameController controller, GameModels models) {
        super();
        this.calleeWindow = calleeWindow;
        this.controller = controller;
        this.models = models;
//        this.WINDOWS_WIDTH = (models.MAP_WIDTH + 2) * UNIT;
//        this.WINDOWS_HEIGHT = (models.MAP_HEIGHT + 2) * UNIT;
        // 组件容器
        JPanel gameMapPanel = new GameMapPanel(models, UNIT); // 游戏绘制器
        JPanel gameTitlePanel = new GameTitlePanel(models); // 游戏信息绘制器
        panels.add(gameMapPanel);
        panels.add(gameTitlePanel);
        Box box = Box.createVerticalBox(); // 创建一个垂直盒子容器, 用于存放所有的面板容器
        box.add(gameTitlePanel);
        box.add(gameMapPanel);
        super.setContentPane(box); // 设置窗口的组件容器
        // 设置窗口
        super.setTitle(TITLE); // 窗口标题
//        super.setPreferredSize(new Dimension(0, gameMapPanel.getHeight() + 2 * UNIT)); // 窗口大小
        super.pack(); // 调整窗口大小以适应内容
//        super.setResizable(false); // 窗口大小是不可改的
        super.setLocationRelativeTo(calleeWindow); // 将新窗口的相对位置设置到调用者窗口的中心
        // 注册事件
        super.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // 关闭窗口时，销毁窗口（而不是整个线程）
        super.addWindowListener(windowListener); // 注册窗口监听器
        super.addKeyListener(keyListener); // 注册键盘监听器
        timer.start();
//        super.setVisible(true); // 最后，显示窗口
    }

    private final Component calleeWindow; // 父窗口
    private final GameController controller; // 游戏控制器
    private final GameModels models; // 游戏模型

    private final List<JPanel> panels = new LinkedList<>(); // 容器队列，均是自定义的绘制器
//    private final JPanel gameMapPanel; // 游戏绘制器
//    private final JPanel gameTitlePanel; // 游戏信息绘制器

    private final KeyListener keyListener = new KeyAdapter() { // 注册键盘监听器
        @Override
        public void keyPressed(KeyEvent e) { // 处理按键事件
            if (models.gameOver) return; // 游戏结束时，锁定画面
            if (controller.updateGameByKeyCode(e.getExtendedKeyCode())) { // 更新游戏进程
                for (JPanel panel : panels) { // 更新画面
                    panel.updateUI();
                }
                timer.restart(); // 重新开始计时
            }
        }
    };

    private final WindowListener windowListener = new WindowAdapter() { // 注册窗口监听器
        @Override
        public void windowClosed(WindowEvent e) { // 处理窗口关闭事件
            super.windowClosed(e);
            calleeWindow.setVisible(true); // 显示原窗口
        }
    };

    private Timer timer = new Timer(TIMER_CYCLE, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (models.gameOver) { // 游戏结束时，锁定画面
                timer.stop();
                return;
            }
            if (controller.timerTriggered()) { // 更新游戏进程
                for (JPanel panel : panels) { // 更新画面
                    panel.updateUI();
                }
            }
        }
    });


}